O(2 ^(k/2))时间内K元素的子集和

 安全小护士 发布于 2023-02-13 10:28

标准子集和问题的一个小变化是我们想要从一组N大小中找到K大小的子集,其总和达到S.

标准的蛮力解决方案产生复杂度O(N ^ K).但是,上面的链接提到了一种蛮力方法的变化,复杂度为O(N ^(K/2)).

维基文章说

已知更好的指数时间算法,其在时间O(2N/2)中运行.该算法任意地将N个元素分成两组N/2.对于这两组中的每一组,它存储其元素的所有2N/2个可能子集的总和的列表.然后对这两个列表中的每一个进行排序.对该步骤使用标准比较排序算法将花费时间O(2N/2N).但是,给定k个元素的和的排序列表,可以通过引入(k + 1)st元素将列表扩展为两个排序列表,并且可以在时间O(2k)中合并这两个排序列表.因此,每个列表可以在时间O(2N/2)中以排序的形式生成.给定两个排序列表,该算法可以检查第一阵列的元素和第二阵列的元素是否在时间O(2N/2)中总和.为此,算法按递减顺序(从最大元素开始)和第二个数组按递增顺序(从最小元素开始)通过第一个数组.只要第一个数组中的当前元素和第二个数组中的当前元素之和大于s,算法就会移动到第一个数组中的下一个元素.如果它小于s,则算法移动到第二个数组中的下一个元素.如果找到两个带有sum的元素,它就会停止.

现在基本上它说如果我们想要找到大小为k的子集,我们计算n个散列大小为K/2的所有子集及其SUM,其中sum是散列中的关键.然后检查是否有两组大小(k)/2)总结到S.

我理解算法,但无法弄清楚,我们怎样才能实现它.散列整数(Sum),其值为列表元组,其中包含实际集合的(K/2)索引.

我们如何在C++中有效地实现它.使用Data sturctures?由于大小(k/2)元素的和,可以并且将是非唯一的,我们不能使用MAP,我们需要多地图,或类似的东西.

1 个回答
  • 从基本的O(2 ^ n)强力算法开始.

    改进的算法,称为中间算法中的meet,将输入列表分成相等大小的一半.前半部分受基本蛮力算法的约束,其中生成所有子集,计算它们的总和,并将总和与目标进行比较.有可能但不太可能在上半年找到目标.如果不是,则算法生成后半部分的所有子集并检查每个总和以查看目标和总和之间的差异是否是前半部分的总和,在这种情况下已找到所需的子集.

    我在我的博客上给出了一个实现.

    2023-02-13 10:30 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有